package com.kuangstudy.controller.redisson;

import io.swagger.models.auth.In;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import sun.rmi.runtime.Log;

import java.util.concurrent.TimeUnit;

/**
 * @author 飞哥
 * @Title: 学相伴出品
 * @Description: 我们有一个学习网站：https://www.kuangstudy.com
 * @date 2021/6/9 12:56
 */
@RestController
@Slf4j
public class RedissonController {

    @Autowired
    private RedissonClient redissonClient;

    @GetMapping("/rlock")
    public void get(String key) throws InterruptedException {
        this.getLock(key, 1);
    }

    private void getLock(String key, int num) throws InterruptedException {
        if (num > 3) {
            return;
        }
        // 1: 获取一个分布式的重入锁RLock
        // 分布式的重入锁RLock,实现了java.util.concurrent.lock.Lock接口。同时还支持自动过期解锁。
        RLock rLock = redissonClient.getLock(key);
        // 2：尝试拿锁
        // 2-1：默认拿锁
        //rLock.tryLock();
        // 2-2：支持过期解锁功能，10秒以后过期自动解锁，无需调用unlock方法手动解锁。
        //rLock.tryLock(10, TimeUnit.SECONDS);
        // 2-3：支持过期解锁功能，最多等待3秒，上锁以后10秒以后过期自动解锁，无需调用unlock方法手动解锁。
        //rLock.tryLock(3,10, TimeUnit.SECONDS);
        boolean flag = rLock.tryLock(3, 10, TimeUnit.SECONDS);
        if (flag) {
            try {
                //执行下单业务
                log.info("线程：{},业务逻辑处理：{},递归的：{}", Thread.currentThread().getName(),
                        key, num);
                // 模拟业务处理时间
                Thread.sleep(5000);

                // 递归实现测试
                this.getLock(key,++num);

            } catch (Exception ex) {
                ex.printStackTrace();
            } finally {
                // 解锁
                rLock.unlock();
                log.info("线程：{},释放锁退出", Thread.currentThread().getName());
            }
        } else {
            log.info("线程：{},未获取到锁", Thread.currentThread().getName());
        }
    }

}
